﻿using ERP.EntityFrameworkCore;
using ERP.ERPModels.RepositoryManage;
using ERP.ProductionManage.Dtos;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ERP.ERPModels.Production.MasterData;

namespace ERP.Web.Controllers
{
    public class SalesoutController : Controller
    {
        private readonly ERPDbContext _dbContext;

        public SalesoutController(ERPDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Edit(int id)
        {
            // 获取销售出库单信息
            var salesout = _dbContext.Set<Salesout>().Find(id);
            if (salesout == null)
            {
                return NotFound();
            }
            
            // 将数据传递给ViewBag
            ViewBag.SalesoutId = salesout.Id;
            ViewBag.OutboundCode = salesout.OutboundCode;
            ViewBag.OutboundName = salesout.OutboundName;
            ViewBag.SalesCode = salesout.SalesCode;
            ViewBag.ClientCode = salesout.ClientCode;
            ViewBag.ClientName = salesout.ClientName;
            ViewBag.OutboundTime = salesout.OutboundTime.ToString("yyyy-MM-dd");
            ViewBag.IsDocuments = salesout.IsDocuments;
            ViewBag.Remark = salesout.Remark;
            
            return View();
        }

        /// <summary>
        /// 获取销售出库列表
        /// </summary>
        /// <param name="queryDto">查询参数</param>
        /// <returns>销售出库列表数据</returns>
        [HttpGet]
        public async Task<IActionResult> GetSalesoutList([FromQuery] SalesoutQueryDto queryDto)
        {
            try
            {
                // 构建查询
                var query = _dbContext.Set<Salesout>().AsQueryable();

                // 应用筛选条件
                if (!string.IsNullOrEmpty(queryDto.OutboundCode))
                {
                    query = query.Where(s => s.OutboundCode.Contains(queryDto.OutboundCode));
                }

                if (!string.IsNullOrEmpty(queryDto.SalesCode))
                {
                    query = query.Where(s => s.SalesCode.Contains(queryDto.SalesCode));
                }

                if (!string.IsNullOrEmpty(queryDto.ClientName))
                {
                    query = query.Where(s => s.ClientName.Contains(queryDto.ClientName));
                }

                if (queryDto.OutboundTime.HasValue)
                {
                    var nextDay = queryDto.OutboundTime.Value.AddDays(1);
                    query = query.Where(s => s.OutboundTime >= queryDto.OutboundTime.Value && s.OutboundTime < nextDay);
                }

                // 单据状态筛选：0-未处理，1-已处理，2-全部（不筛选）
                if (queryDto.IsDocuments.HasValue && queryDto.IsDocuments.Value != 2)
                {
                    query = query.Where(s => s.IsDocuments == queryDto.IsDocuments.Value);
                }

                // 计算总记录数
                int totalCount = await query.CountAsync();

                // 应用分页
                var items = await query
                    .OrderByDescending(s => s.OutboundTime)
                    .Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
                    .Take(queryDto.PageSize)
                    .ToListAsync();

                // 返回结果
                return Json(new
                {
                    code = 0,
                    msg = "获取成功",
                    count = totalCount,
                    data = items
                });
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    code = 1,
                    msg = $"获取销售出库列表失败：{ex.Message}",
                    count = 0,
                    data = new List<Salesout>()
                });
            }
        }

        /// <summary>
        /// 添加销售出库单
        /// </summary>
        /// <param name="salesout">销售出库单数据</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> AddSalesout([FromBody] Salesout salesout)
        {
            try
            {
                // 数据验证
                if (salesout == null)
                {
                    return Json(new { code = 1, msg = "无效的销售出库单数据" });
                }

                if (string.IsNullOrEmpty(salesout.OutboundCode))
                {
                    return Json(new { code = 1, msg = "出库单编号不能为空" });
                }

                if (string.IsNullOrEmpty(salesout.OutboundName))
                {
                    return Json(new { code = 1, msg = "出库单名称不能为空" });
                }

                if (string.IsNullOrEmpty(salesout.ClientCode))
                {
                    return Json(new { code = 1, msg = "客户编码不能为空" });
                }


                // 创建销售出库单实体
                var newSalesout = new Salesout
                {
                    OutboundCode = salesout.OutboundCode,
                    OutboundName = salesout.OutboundName,
                    SalesCode = salesout.SalesCode,
                    ClientCode = salesout.ClientCode,
                    ClientName = salesout.ClientName,
                    OutboundTime = salesout.OutboundTime,
                    IsDocuments = salesout.IsDocuments,
                    Remark = salesout.Remark
                };

                // 保存到数据库
                await _dbContext.Set<Salesout>().AddAsync(newSalesout);
                await _dbContext.SaveChangesAsync();

                return Json(new
                {
                    code = 0,
                    msg = "添加成功",
                    data = newSalesout
                });
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    code = 1,
                    msg = $"添加销售出库单失败：{ex.Message}"
                });
            }
        }

        /// <summary>
        /// 删除销售出库单
        /// </summary>
        /// <param name="id">销售出库单ID</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> DeleteSalesout(int id)
        {
            try
            {
                var salesout = await _dbContext.Set<Salesout>().FindAsync(id);
                if (salesout == null)
                {
                    return Json(new { code = 1, msg = "未找到要删除的销售出库单" });
                }

                _dbContext.Set<Salesout>().Remove(salesout);
                await _dbContext.SaveChangesAsync();

                return Json(new { code = 0, msg = "删除成功" });
            }
            catch (Exception ex)
            {
                return Json(new { code = 1, msg = $"删除销售出库单失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 批量删除销售出库单
        /// </summary>
        /// <param name="ids">销售出库单ID列表</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> BatchDelete([FromBody] List<int> ids)
        {
            try
            {
                if (ids == null || ids.Count == 0)
                {
                    return Json(new { code = 1, msg = "请选择要删除的销售出库单" });
                }

                var salesouts = await _dbContext.Set<Salesout>()
                    .Where(s => ids.Contains(s.Id))
                    .ToListAsync();

                if (salesouts.Count == 0)
                {
                    return Json(new { code = 1, msg = "未找到要删除的销售出库单" });
                }

                _dbContext.Set<Salesout>().RemoveRange(salesouts);
                await _dbContext.SaveChangesAsync();

                return Json(new { code = 0, msg = "批量删除成功" });
            }
            catch (Exception ex)
            {
                return Json(new { code = 1, msg = $"批量删除销售出库单失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取新的出库单编号
        /// </summary>
        /// <returns>自动生成的出库单编号</returns>
        [HttpGet]
        public IActionResult GetNewOutboundCode()
        {
            try
            {
                // 生成出库单编号：CK + 年月日时分秒毫秒 + 3位随机数
                string code = "CK" + DateTime.Now.ToString("yyyyMMddHHmmssfff") 
                    + new Random().Next(100, 999).ToString();
                
                return Json(new { code = 0, msg = "获取编号成功", data = code });
            }
            catch (Exception ex)
            {
                return Json(new { code = 1, msg = $"获取出库单编号失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取客户列表，用于客户选择弹窗
        /// </summary>
        /// <param name="customerCode">客户编码</param>
        /// <param name="customerName">客户名称</param>
        /// <param name="shortName">客户简称</param>
        /// <param name="enName">客户英文名称</param>
        /// <param name="isEnabled">是否启用</param>
        /// <param name="page">页码</param>
        /// <param name="limit">每页条数</param>
        /// <returns>客户列表数据</returns>
        [HttpGet]
        public async Task<IActionResult> GetCustomerList(
            string? customerCode, 
            string? customerName, 
            int? isEnabled,
            int page, 
            int limit)
        {
            try
            {
                // 构建查询
                var query = _dbContext.Set<Customers>().AsQueryable();

                // 应用筛选条件
                if (!string.IsNullOrEmpty(customerCode))
                {
                    query = query.Where(c => c.CustomerCode.Contains(customerCode));
                }

                if (!string.IsNullOrEmpty(customerName))
                {
                    query = query.Where(c => c.CustomerName.Contains(customerName));
                }

                // 是否启用筛选
                if (isEnabled.HasValue)
                {
                    query = query.Where(c => c.IsNo == isEnabled.Value);
                }

                // 计算总记录数
                int totalCount = await query.CountAsync();

                // 应用分页
                var items = await query
                    .OrderBy(c => c.CustomerCode)
                    .Skip((page - 1) * limit)
                    .Take(limit)
                    .ToListAsync();

                // 构建返回结果
                var result = new
                {
                    code = 0,
                    msg = "获取成功",
                    count = totalCount,
                    data = items.Select(c => new
                    {
                        c.Id,
                        c.CustomerCode,
                        c.CustomerName,
                        c.CustomerType,
                        c.CustomerPhone,
                        ContactPerson = "", // 这里暂时为空，实际项目中可能需要从其他表获取
                        ContactPhone = "", // 这里暂时为空，实际项目中可能需要从其他表获取
                        IsEnabled = c.IsNo
                    }).ToList()
                };

                // 返回结果
                return Json(result);
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    code = 1,
                    msg = $"获取客户列表失败：{ex.Message}",
                    count = 0,
                    data = new List<object>()
                });
            }
        }

        /// <summary>
        /// 获取销售出库单明细物料信息
        /// </summary>
        [HttpGet]
        public async Task<IActionResult> GetSalesoutData(int salesoutId, int page = 1, int limit = 5)
        {
            try
            {
                // 构建查询
                var query = _dbContext.Set<SalesoutDetail>().AsQueryable();
                
                // 必须按销售出库单ID筛选
                if (salesoutId > 0)
                {
                    query = query.Where(d => d.SalesoutId == salesoutId);
                }
                else
                {
                    // 如果没有提供有效的salesoutId，返回空结果
                    return Json(new { code = 0, msg = "获取成功", count = 0, data = new List<SalesoutDetail>() });
                }

                // 计算总记录数和获取分页数据
                var totalCount = await query.CountAsync();
                var items = await query
                    .OrderBy(c => c.Id)
                    .Skip((page - 1) * limit)
                    .Take(limit)
                    .ToListAsync();

                // 返回结果
                return Json(new { code = 0, msg = "获取成功", count = totalCount, data = items });
            }
            catch (Exception ex)
            {
                return Json(new { code = 1, msg = $"获取销售出库单明细失败：{ex.Message}", count = 0, data = new List<object>() });
            }
        }
        
        /// <summary>
        /// 删除销售出库单明细物料信息
        /// </summary>
        /// <param name="id">物料明细ID</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> DeleteSalesoutDetail(int id)
        {
            try
            {
                var detail = await _dbContext.Set<SalesoutDetail>().FindAsync(id);
                if (detail == null)
                {
                    return Json(new { code = 1, msg = "未找到要删除的物料信息" });
                }

                _dbContext.Set<SalesoutDetail>().Remove(detail);
                await _dbContext.SaveChangesAsync();

                return Json(new { code = 0, msg = "删除成功" });
            }
            catch (Exception ex)
            {
                return Json(new { code = 1, msg = $"删除物料信息失败：{ex.Message}" });
            }
        }
        
        /// <summary>
        /// 新增销售出库单明细物料信息
        /// </summary>
        /// <param name="detail">物料明细实体</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> AddSalesoutDetail([FromBody] SalesoutDetailUpdListDto detail)
        {
            try
            {
                // 添加详细日志
                Console.WriteLine($"接收到的新增物料数据: 产品编码={detail.ProductCode}, 仓库ID={detail.WarehouseId}");
                
                // 参数验证
                if (detail == null)
                    return Json(new { code = 1, msg = "新增物料信息失败: 无效的物料数据" });

                if (detail.SalesoutId <= 0)
                    return Json(new { code = 1, msg = "新增物料信息失败: 无效的销售出库单ID" });

                // 不能直接修改Id，使用EF Core的方式添加
                var salesoutDetail = new SalesoutDetail
                {
                    SalesoutId = detail.SalesoutId,
                    ProductCode = detail.ProductCode,
                    ProductName = detail.ProductName,
                    Specification = detail.Specification ?? string.Empty,
                    Unit = detail.Unit,
                    Quantity = detail.Quantity,
                    BatchNumber = detail.BatchNumber ?? string.Empty,
                    WarehouseId = detail.WarehouseId,
                    StorageAreaId = detail.StorageAreaId,
                    IsInspected = detail.IsInspected,
                    InspectionCode = detail.IsInspected ? $"INS{DateTime.Now:yyyyMMdd}{new Random().Next(1000, 9999)}" : string.Empty,
                    Remark = detail.Remark ?? string.Empty,
                    // 设置仓库和库区名称
                    WarehouseName = GetWarehouseName(detail.WarehouseId),
                    StorageAreaName = GetStorageAreaName(detail.StorageAreaId)
                };
                
                // 保存到数据库
                _dbContext.Set<SalesoutDetail>().Add(salesoutDetail);
                await _dbContext.SaveChangesAsync();

                return Json(new { code = 0, msg = "新增物料信息成功" });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"新增物料信息异常: {ex.Message}");
                Console.WriteLine($"内部异常: {ex.InnerException?.Message}");
                return Json(new { code = 1, msg = $"新增物料信息失败: {ex.Message}" });
            }
        }
        
        /// <summary>
        /// 获取仓库名称
        /// </summary>
        /// <param name="warehouseId">仓库ID</param>
        /// <returns>仓库名称</returns>
        private string GetWarehouseName(int warehouseId)
        {
            return warehouseId switch
            {
                1 => "主仓库",
                2 => "成品仓库",
                3 => "原材料仓库",
                4 => "辅料仓库",
                5 => "不合格品仓库",
                _ => $"仓库{warehouseId}"
            };
        }
        
        /// <summary>
        /// 获取库区名称
        /// </summary>
        /// <param name="storageAreaId">库区ID</param>
        /// <returns>库区名称</returns>
        private string GetStorageAreaName(int storageAreaId)
        {
            return storageAreaId switch
            {
                1 => "A区",
                2 => "B区",
                3 => "C区",
                4 => "D区",
                5 => "E区",
                _ => $"库区{storageAreaId}"
            };
        }

        /// <summary>
        /// 更新销售出库单明细物料信息
        /// </summary>
        /// <param name="detail">物料明细实体</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> UpdateSalesoutDetail([FromBody] SalesoutDetailUpdListDto detail)
        {
            try
            {
                // 添加详细日志
                Console.WriteLine($"接收到的物料数据: ID={detail.Id}, 产品编码={detail.ProductCode}, 仓库ID={detail.WarehouseId}");
                
                // 参数验证
                if (detail == null)
                    return Json(new { code = 1, msg = "更新物料信息失败: 无效的物料数据" });

                if (detail.Id <= 0)
                {
                    Console.WriteLine($"无效的ID值: {detail.Id}");
                    return Json(new { code = 1, msg = $"更新物料信息失败: 无效的物料ID，必须提供有效ID" });
                }

                // 直接查找要更新的记录，只使用ID
                var existingDetail = await _dbContext.Set<SalesoutDetail>().FindAsync(detail.Id);

                if (existingDetail == null)
                {
                    Console.WriteLine($"未找到ID为{detail.Id}的物料记录");
                    return Json(new { code = 1, msg = $"未找到ID为{detail.Id}的物料记录" });
                }

                // 更新字段
                existingDetail.ProductCode = detail.ProductCode;
                existingDetail.ProductName = detail.ProductName;
                existingDetail.Specification = detail.Specification ?? string.Empty;
                existingDetail.Unit = detail.Unit;
                existingDetail.Quantity = detail.Quantity;
                existingDetail.BatchNumber = detail.BatchNumber ?? string.Empty;
                existingDetail.WarehouseId = detail.WarehouseId;
                existingDetail.StorageAreaId = detail.StorageAreaId;
                existingDetail.IsInspected = detail.IsInspected;
                existingDetail.Remark = detail.Remark ?? string.Empty;
                
                // 更新仓库和库区名称
                existingDetail.WarehouseName = GetWarehouseName(detail.WarehouseId);
                existingDetail.StorageAreaName = GetStorageAreaName(detail.StorageAreaId);
                
                // 如果是检验项目且检验编号为空，则生成检验编号
                if (detail.IsInspected && string.IsNullOrEmpty(existingDetail.InspectionCode))
                {
                    existingDetail.InspectionCode = $"INS{DateTime.Now:yyyyMMdd}{new Random().Next(1000, 9999)}";
                }
                else if (!detail.IsInspected)
                {
                    existingDetail.InspectionCode = string.Empty;
                }

                await _dbContext.SaveChangesAsync();

                return Json(new { code = 0, msg = "更新物料信息成功" });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"更新物料信息异常: {ex.Message}");
                Console.WriteLine($"内部异常: {ex.InnerException?.Message}");
                return Json(new { code = 1, msg = $"更新物料信息失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 获取销售出库单明细物料信息
        /// </summary>
        /// <param name="id">物料ID</param>
        /// <returns>物料信息</returns>
        [HttpGet]
        public async Task<IActionResult> GetSalesoutDetailById(int id)
        {
            try
            {
                if (id <= 0)
                    return Json(new { code = 1, msg = "无效的物料ID" });

                // 查询物料信息
                var detail = await _dbContext.Set<SalesoutDetail>().FindAsync(id);
                
                if (detail == null)
                    return Json(new { code = 1, msg = $"未找到ID为{id}的物料记录" });
                
                // 将实体转换为DTO
                var detailDto = new SalesoutDetailUpdListDto
                {
                    Id = detail.Id,
                    SalesoutId = detail.SalesoutId,
                    ProductCode = detail.ProductCode,
                    ProductName = detail.ProductName,
                    Specification = detail.Specification,
                    Unit = detail.Unit,
                    Quantity = detail.Quantity,
                    BatchNumber = detail.BatchNumber,
                    WarehouseId = detail.WarehouseId,
                    WarehouseName = detail.WarehouseName,
                    StorageAreaId = detail.StorageAreaId,
                    StorageAreaName = detail.StorageAreaName,
                    IsInspected = detail.IsInspected,
                    InspectionCode = detail.InspectionCode,
                    Remark = detail.Remark
                };

                return Json(new { code = 0, msg = "获取成功", data = detailDto });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取物料信息异常: {ex.Message}");
                return Json(new { code = 1, msg = $"获取物料信息失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 更新销售出库单
        /// </summary>
        /// <param name="salesout">销售出库单数据</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> UpdateSalesout([FromBody] Salesout salesout)
        {
            try
            {
                // 数据验证
                if (salesout == null)
                {
                    return Json(new { code = 1, msg = "无效的销售出库单数据" });
                }

                if (salesout.Id <= 0)
                {
                    return Json(new { code = 1, msg = "无效的销售出库单ID" });
                }

                if (string.IsNullOrEmpty(salesout.OutboundName))
                {
                    return Json(new { code = 1, msg = "出库单名称不能为空" });
                }

                if (string.IsNullOrEmpty(salesout.ClientCode))
                {
                    return Json(new { code = 1, msg = "客户编码不能为空" });
                }

                // 查找要更新的记录
                var existingSalesout = await _dbContext.Set<Salesout>().FindAsync(salesout.Id);
                
                if (existingSalesout == null)
                {
                    return Json(new { code = 1, msg = $"未找到ID为{salesout.Id}的销售出库单" });
                }

                // 更新字段
                existingSalesout.OutboundName = salesout.OutboundName;
                existingSalesout.SalesCode = salesout.SalesCode;
                existingSalesout.ClientCode = salesout.ClientCode;
                existingSalesout.ClientName = salesout.ClientName;
                existingSalesout.OutboundTime = salesout.OutboundTime;
                existingSalesout.IsDocuments = salesout.IsDocuments;
                existingSalesout.Remark = salesout.Remark ?? string.Empty;
                
                // 保存到数据库
                await _dbContext.SaveChangesAsync();

                return Json(new
                {
                    code = 0,
                    msg = "更新成功",
                    data = existingSalesout
                });
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    code = 1,
                    msg = $"更新销售出库单失败：{ex.Message}"
                });
            }
        }
    }
}
